/*
 * ...
 */

package com.ruoyi.common.utils.file;

import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.framework.config.RuoYiConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * @author 挺好的 2023年11月06日 下午 15:54
 */
@Slf4j
public class ImagUtils {


    /**
     * 图片压缩
     * @param file
     * @return
     * @throws Exception
     */
    public static MultipartFile uploadImagPoster (MultipartFile file) throws Exception {
        String filePath = RuoYiConfig.getProfile();
        if(ObjectUtil.isNotEmpty(filePath)){
           // filePath= filePath+"/"+ DateUtils.getDate()+"/";
            filePath= filePath+"/";
        }
        // 上传的jpg图片文件名, 不管压缩还是不压缩, 都要保证最后文件的名称就是originalFilename
        final String originalFilename = file.getOriginalFilename();
        String suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));//获取文件后缀名

        if(!isImage(suffixName.replace(".",""))){
            throw new RuntimeException("请上传正确格式图片");
        }
        // 文件大小 && 转KB
        long size = file.getSize();
        int sizeKb = (int) ((size / 1024) + 1);
        log.info("上传文件:{}, 大小是:{}KB", originalFilename, sizeKb);

        // 目标文件
        File targetFile = new File(filePath, originalFilename);
        // 不管上传的图片大小, 先上传上去, 在判断大小或压缩
        file.transferTo(targetFile);
        if (sizeKb > 300) {
            // 文件递归压缩的时候, 过程中文件名称变化的标识
            int identity = 0;
            // 压缩
            while (sizeKb > 300) {
                identity++;
                // 上一次的目标文件, 作为本次压缩的源文件
                String fileName = targetFile.getName();
                final File sourceFile = new File(filePath, fileName);
                // 目标文件， SystemYs 和 变量identity 都是每次压缩文件重命名的格式
                // 测试过，同一个文件不能自己对自己进行压缩，所以进行重命名
                String targetFileName = "SystemYs" + identity + "-" + originalFilename;
                targetFile = new File(filePath, targetFileName);
                // 源文件IO流
                final InputStream in = new FileInputStream(sourceFile);
                // 目标文件IO流
                final OutputStream out = new FileOutputStream(targetFile);
                // 压缩（Hutool工具类，三个参数说明看API即可，很简单）
                ImgUtil.scale(in, out, 0.8f);
                // 关闭流
                out.close();
                in.close();
                // 压缩完了之后, 删除源文件
                sourceFile.delete();
                size = targetFile.length();
                sizeKb = (int) ((size / 1024) + 1);
                log.info("递归压缩, 压缩之后文件:{}, 大小:{}KB", fileName, sizeKb);
            }
            // 递归压缩后, 图片<=30KB了, 进行文件重命名
            //targetFile.renameTo(new File(filePath, originalFilename));
            MultipartFile multipartFile = fileToMultipartFile(targetFile);
            return multipartFile;
        }
        MultipartFile multipartFile = fileToMultipartFile(targetFile);
        return multipartFile;
    }

    /**
     * 根据文件扩展名判断文件是否图片格式
     *
     * @param extension 文件扩展名
     * @return
     */
    public static boolean isImage(String extension) {
        String[] imageExtension = new String[]{"jpeg", "jpg", "gif", "bmp", "png"};
        for (String e : imageExtension) if (extension.toLowerCase().equals(e)) return true;
        return false;
    }

    /**
     * 文件转换
     * @param file
     * @return
     */
    public static MultipartFile fileToMultipartFile (File file) {
        FileItem fileItem = createFileItem(file);
        MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
        return multipartFile;
    }

    private static FileItem createFileItem(File file) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item = factory.createItem("textField", "text/plain", true, file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return item;
    }

    public static void main (String[] args) throws Exception {
        File file = new File("D:\\11.jpg");
        MultipartFile multipartFile = fileToMultipartFile(file);
        uploadImagPoster(multipartFile);
        //System.out.println(s);

       /* //原
        File source = new File("F:\\MP4\\old\\1.mp4");
        //新
        File target = new File("F:\\MP4\\new\\1.mp4");
        try {
            System.out.println("begin");
            AudioAttributes audio = new AudioAttributes();
            audio.setCodec("libmp3lame");
            audio.setBitRate(new Integer(56000));
            audio.setChannels(new Integer(1));
            audio.setSamplingRate(new Integer(22050));
            VideoAttributes video = new VideoAttributes();
            video.setCodec("mpeg4");
            video.setBitRate(new Integer(800000));
            video.setFrameRate(new Integer(15));
            EncodingAttributes attr = new EncodingAttributes();
            attr.setFormat("mp4");
            attr.setAudioAttributes(audio);
            attr.setVideoAttributes(video);
            Encoder encoder = new Encoder();
            encoder.encode(source, target, attr);
            System.out.println("end");
        } catch (Exception e) {
            e.printStackTrace();
        }*/

    }

}
